package com.jrx.anytxn.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.customer.constant.CouponConstant;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.dto.BaseApiReq;
import com.jrx.anytxn.customer.dto.coupon.CouponChargeOffReq;
import com.jrx.anytxn.customer.dto.coupon.CouponTrialReq;
import com.jrx.anytxn.customer.dto.coupon.CouponTrialRes;
import com.jrx.anytxn.customer.dto.rights.CmCustomerRightsRes;
import com.jrx.anytxn.customer.dto.rights.CustRightRes;
import com.jrx.anytxn.customer.dto.rights.CustomerRightRes;
import com.jrx.anytxn.customer.dto.rights.CustomerRightResByCms;
import com.jrx.anytxn.customer.entity.CmCustomerRightInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.TlCouponUseLog;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerRightInfoMapper;
import com.jrx.anytxn.customer.service.ICustomerRightService;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.customer.service.ITlCouponUseService;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.dto.partner.PmMerchantTableRes;
import com.jrx.anytxn.param.entity.PrRightsAndInterestsRes;
import com.jrx.anytxn.param.dto.rights.PrRightsQualificationRes;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.PrRightsAndInterests;
import com.jrx.anytxn.param.entity.PrRightsQualification;
import com.jrx.anytxn.param.enums.RightsTypeEnum;
import com.jrx.anytxn.param.service.partner.IPmMerchantTableService;
import com.jrx.anytxn.param.service.rights.IPrRightsAndInterestsService;
import com.jrx.anytxn.param.service.rights.IPrRightsQualificationService;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 客户权益信息查询service
 */
@Service
public class CustomerRightServiceImpl implements ICustomerRightService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerRightServiceImpl.class);

    @Autowired
    private ICustomerService customerService;
    @Resource
    private ExtCmCustomerRightInfoMapper extCmCustomerRightInfoMapper;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private IPrRightsQualificationService prRightsQualificationService;
    @Autowired
    private IPrRightsAndInterestsService prRightsAndInterestsService;
    @Autowired
    private ITlCouponUseService couponUseService;
    @Autowired
    private ISegmentService iSegmentService;
    @Autowired
    private IPmMerchantTableService pmMerchantTableService;
    @Override
    public CustomerRightRes getCustomerRight(BaseApiReq baseApiReq) throws TxnBizException {
        CustomerRightRes res = new CustomerRightRes();
        // 验证客户是否存在
        CmCustomerSecondLevel customer = customerService.getSecondLevelByCondition(baseApiReq.getUserId(),
            baseApiReq.getChannel(), baseApiReq.getTenantId(), null);
        res.setTenantId(baseApiReq.getTenantId());
        res.setChannel(baseApiReq.getChannel());
        res.setUserId(baseApiReq.getUserId());

        // 1 获取业务日期
        PrOrganizationTable org =
            organizationTableService.findByOrId(customer.getOrganizationId(), baseApiReq.getTenantId());
        Date businessDate = org.getNextProcessingDate();
        res.setBusinessDate(businessDate);

        // 查询客户权益表
        List<CmCustomerRightInfo> infoList = extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndChannel(
            customer.getCustomerId(), customer.getTenantId(), baseApiReq.getChannel());
        if (CollectionUtils.isEmpty(infoList)) {
            res.setCustRightList(Collections.emptyList());
            return res;
        }

        List<CustRightRes> rightResList = new ArrayList<>();
        for (CmCustomerRightInfo info : infoList) {
            CustRightRes custRightRes = BeanMapping.copy(info, CustRightRes.class);
            custRightRes.setCustRightId(info.getId());
            rightResList.add(custRightRes);
        }
        res.setCustRightList(rightResList);
        return res;
    }

    @Override
    public TxnPage<CmCustomerRightsRes> getRightsWithPage(String channel, String customerId, String tenantId,
        Integer pageNum, Integer pageSize) {
        Page<CmCustomerRightInfo> page = PageHelper.startPage(pageNum, pageSize);
        List<CmCustomerRightInfo> cmCustomerRightInfoList =
            extCmCustomerRightInfoMapper.selectByPage(tenantId, channel, customerId);
        if (CollectionUtils.isNotEmpty(cmCustomerRightInfoList)) {
            for (CmCustomerRightInfo info : cmCustomerRightInfoList) {
                if (Constant.RIGHTS_TYPE_01.equals(info.getRightsType())) {
                    info.setDiscountRate(BigDecimal.valueOf(info.getDiscountDays()));
                }
            }
        }
        List<CmCustomerRightsRes> res = BeanMapping.copyList(cmCustomerRightInfoList, CmCustomerRightsRes.class);
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    @Override
    public CmCustomerRightsRes getCustomerRightByIdAndCustomerId(Long id, String customerId, String tenantId) {
        CmCustomerRightInfo info =
            extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndId(customerId, tenantId, id);
        if (null != info) {
            if (Constant.RIGHTS_TYPE_01.equals(info.getRightsType())) {
                info.setDiscountRate(BigDecimal.valueOf(info.getDiscountDays()));
            }
        }
        return BeanMapping.copy(info, CmCustomerRightsRes.class);
    }

    @Override
    public CustomerRightResByCms getCustomerRightByLoanIdAndCustomerId(String loanId, String customerId,
        String tenantId) throws TxnBizException {
        CustomerRightResByCms cms = new CustomerRightResByCms();
        CmCustomerRightInfo table =
            extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndLoanId(customerId, tenantId, loanId);
        // 只有生效才显示
        if (null != table && Constant.STATUS_1.equals(table.getRightsStatus())) {
            cms.setId(table.getId() + "");
            cms.setRightsName(table.getRightsName());
        }
        return cms;
    }

    @Override
    public CmCustomerRightInfo getByCustomerIdAndTenantIdAndLoanId(String customerId, String tenantId, String loanId) {
        CmCustomerRightInfo cmCustomerRightInfo =
            extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndLoanId(customerId, tenantId, loanId);
        return cmCustomerRightInfo;
    }

    /**
     * 根据优惠券id获取优惠券
     * 
     * @param custRightId
     * @param customerId
     * @param tenantId
     * @return
     * @throws TxnBizException
     */
    @Override
    public CmCustomerRightInfo getRightInfoById(Long custRightId, String customerId, String tenantId)
        throws TxnBizException {
        CmCustomerRightInfo cmCustomerRightInfo =
            extCmCustomerRightInfoMapper.selectByCustRightId(custRightId, customerId, tenantId);
        if (null == cmCustomerRightInfo) {
            throw new TxnBizException(TxnRespCode.CUSTOMER_RIGHT_NOT_EXIT.getCode(),
                TxnRespCode.CUSTOMER_RIGHT_NOT_EXIT.getUserTips());
        }
        return cmCustomerRightInfo;
    }

    /**
     * 更新优惠券状态
     * 
     * @param custRightId
     * @param loanId
     * @param rightsStatus
     * @param customerId
     * @param tenantId
     */
    @Override
    public void updateCustRight(Long custRightId, String loanId, String rightsStatus, String customerId,
        String tenantId) {
        extCmCustomerRightInfoMapper.updateCustRight(custRightId, loanId, rightsStatus, tenantId, customerId);
    }

    /**
     * 根据 客户号、租户号、权益id、活动号 查询客户权益信息表
     *
     * @param customerId
     * @param tenantId
     * @param rightsId
     * @param activityId
     * @return
     */
    @Override
    public CmCustomerRightInfo selectByCustomerIdAndTenantIdAndRightsIdAndActivityId(String customerId, String tenantId,
        String rightsId, String activityId) {
        return extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndRightsIdAndActivityId(customerId, tenantId,
            rightsId, activityId);
    }

    /**
     * 根据 客户号、租户号、权益资格id、活动号 查询客户权益信息表
     *
     * @param customerId
     * @param tenantId
     * @param qualificationId
     * @param activityId
     * @return
     */
    @Override
    public List<CmCustomerRightInfo> selectByCustomerIdAndTenantIdAndQualificationIdAndActivityId(String customerId,
        String tenantId, String qualificationId, String activityId) {
        return extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndQualificationIdAndActivityId(customerId,
            tenantId, qualificationId, activityId);
    }

    /**
     * 根据客户id、租户号、权益类型列表 查询 客户权益信息
     *
     * @param customerId
     * @param tenantId
     * @param rightsTypeList
     * @return
     */
    @Override
    public List<CustRightRes> getByCustomerIdAndTenantIdAndChannelAndRightsTypeList(String customerId, String tenantId,
        String channel, List<String> rightsTypeList) {
        List<CmCustomerRightInfo> customerRightInfoList =
            extCmCustomerRightInfoMapper.selectByCustomerIdAndTenantIdAndChannel(customerId, tenantId, channel);
        List<CustRightRes> custRightResList = new ArrayList<>();

        // 注：该方法执行之后，CustRightRes.custRightId 为空，CustRightRes.id 为 CmCustomerRightInfo.id
        BeanUtils.copyList(customerRightInfoList, custRightResList, CustRightRes.class);

        List<PrRightsAndInterestsRes> prRightsAndInterestsList =
                prRightsAndInterestsService.findAllByTenId(tenantId);


        return custRightResList.stream()
                .filter(item -> rightsTypeList.contains(item.getRightsType()))
                .map(item -> {
                    // 设置规则
                    String rightsId = item.getRightsId();
                    Optional<PrRightsAndInterestsRes> resOptional = prRightsAndInterestsList.stream().filter(right -> StringUtils.isNotBlank(right.getRightsId()) && right.getRightsId().equals(rightsId)).findFirst();
                    if (resOptional != null && resOptional.isPresent()) {
                        item.setRightsUseRule(resOptional.get().getRightsDesc());
                        item.setRightsSubName(resOptional.get().getRightsSubName());
                        String merchantIds = resOptional.get().getMerchantId();
                        if (StringUtils.isNotBlank(merchantIds)) {
                            Optional<String> merchantId = Arrays.stream(merchantIds.split(",")).findFirst();
                            if (merchantId != null && merchantId.isPresent()) {
                                try {
                                    PmMerchantTableRes merchantTableRes = pmMerchantTableService.getByTenIdIdAndMerchanId(tenantId, merchantId.get());
                                    if (StringUtils.isNotBlank(merchantTableRes.getAppletJumpLink()) && StringUtils.isNotBlank(merchantTableRes.getAppletAppId())){
                                        item.setEnableJumpFlag("1");
                                        item.setAppletJumpLink(merchantTableRes.getAppletJumpLink());
                                        item.setAppletAppId(merchantTableRes.getAppletAppId());
                                    }
                                } catch (TxnBizException txnBizException) {
                                    LOGGER.info("获取商户信息异常");
                                }
                            }
                        }
                    }
                    if(CouponConstant.CYCLE_USE_Y.equals(item.getCycleUse()) && item.getDiscountAmtUsed() == null){
                        item.setDiscountAmtUsed(BigDecimal.ZERO);
                    }

                    // 日期是否生效标志
                    Date today = new Date();
                    item.setDateEffectiveState(CouponConstant.DATE_IN_EFFECTIVE);
                    if (today.before(item.getEffectDate())) {
                        item.setDateEffectiveState(CouponConstant.DATE_NOT_EFFECTIVE);
                    }
                    Date expireDate = item.getExpiresDate();
                    expireDate = DateUtils.addDay(expireDate, 1);
                    if (today.after(expireDate)) {
                        item.setDateEffectiveState(CouponConstant.DATE_IN_EXPIRE);
                    }
                    // 如果是权益资格类，设置待兑换候选权益
                    if (RightsTypeEnum.QUALIFICATION.getCode().equals(item.getRightsType())) {
                        String qualificationId = item.getRightsQualificationId();
                        if (StringUtils.isNotBlank(qualificationId)) {
                            String[] qualiIds = qualificationId.split(",");
                            List<PrRightsQualificationRes> qualificationResList = new ArrayList<>();
                            for (int j = 0; j < qualiIds.length; j++) {

                                String quaId = qualiIds[j];

                                PrRightsQualification prRightsQualification =
                                        prRightsQualificationService.getByTenantIdAndQualificationId(tenantId, quaId);
                                if (prRightsQualification != null) {
                                    PrRightsQualificationRes tmp = new PrRightsQualificationRes();
                                    org.springframework.beans.BeanUtils.copyProperties(prRightsQualification,tmp);
                                    qualificationResList.add(tmp);
                                }
                            }
                            item.setQualificationCandidate(qualificationResList.stream().sorted(Comparator.comparing(PrRightsQualificationRes::getQualificationType).reversed()).collect(Collectors.toList()));
                            item.setLogoUrl(qualificationResList.get(0).getLogoUrl());
                        }
                    }
                    return item;
        }).collect(Collectors.toList());
    }

    /**
     * 获取 客户指定权益列表
     *
     * @param userId
     * @param tenantId
     * @param rightsTypeList
     * @return
     */
    @Override
    public List<CustRightRes> listByCustomerRightsType(String userId, String tenantId, String channel,
                                                       List<String> rightsTypeList) throws TxnBizException {
        CmCustomerSecondLevel customer = customerService.getSecondLevelByCondition(userId, channel, tenantId, null);
        if (customer == null) {
            LOGGER.info("根据 userId:{}、channel:{}、tenantId:{} 查询客户二级信息表，查无记录", userId, channel, tenantId);
            throw new TxnBizException(TxnRespCode.NO_DATA);
        }
        return getByCustomerIdAndTenantIdAndChannelAndRightsTypeList(customer.getCustomerId(), tenantId, channel,
                rightsTypeList);
    }

    /**
     * 优惠券 消费时现金抵消试算
     *
     * @param trialReq
     * @return
     */
    @Override
    public CouponTrialRes couponTrial(CouponTrialReq trialReq) throws TxnBizException {
        if (StringUtils.isBlank(trialReq.getProductId())) {
            trialReq.setProductId(BizTypeProducts.PRODUCT_XAH.get(0));
        }

        if(LOGGER.isInfoEnabled()){
            LOGGER.info("优惠券试算请求：{}", JSON.toJSONString(trialReq));
        }

        CouponTrialRes result = new CouponTrialRes();
        CmCustomerSecondLevel customer = customerService.getSecondLevelByCondition(trialReq.getUserId(), trialReq.getChannel(), trialReq.getTenantId(), null);
        if (customer == null) {
            LOGGER.info("根据 userId:{}、channel:{}、tenantId:{} 查询客户二级信息表，查无记录", trialReq.getUserId(), trialReq.getChannel(), trialReq.getTenantId());
            throw new TxnBizException(TxnRespCode.NO_DATA);
        }

        List<String> couponTypeList = new ArrayList<>(Arrays.asList(RightsTypeEnum.CASH_COUPON.getCode(),RightsTypeEnum.DISCOUNT_COUPON.getCode()));
        List<CustRightRes> custRightResList = listByCustomerRightsType(trialReq.getUserId(), trialReq.getTenantId(), trialReq.getChannel(),
                couponTypeList);

        List<CustRightRes> availableCouponList = custRightResList.stream()
                .filter(item -> CouponConstant.DATE_IN_EFFECTIVE.equals(item.getDateEffectiveState()))
                .filter(item -> CouponConstant.RIGHTS_STATUS_UNUSED.equals(item.getRightsStatus()) ||
                        CouponConstant.RIGHTS_STATUS_USED_PARTLY.equals(item.getRightsStatus()))
                .collect(Collectors.toList());
        if(LOGGER.isInfoEnabled()){
            LOGGER.info("权益试算时客户优惠券权益列表：{}", JSON.toJSONString(availableCouponList));
        }
        BigDecimal trialAmount = BigDecimal.ZERO;
        // 交易金额
        BigDecimal tranAmt = trialReq.getTranAmt().setScale(2, BigDecimal.ROUND_HALF_UP);

        for (CustRightRes custRightRes : availableCouponList) {
            /**
             * 当前发生交易的产品不存在于该优惠券适用产品列表
             */
            if (!custRightRes.getAllowProducts().contains(trialReq.getProductId())) {
                LOGGER.info("当前发生交易的产品{}不存在于该优惠券适用产品列表{}", trialReq.getProductId(), custRightRes.getAllowProducts());
                continue;
            }
            /**
             * 过滤商户id不符合的数据
             */
            String rightsId = custRightRes.getRightsId();
            PrRightsAndInterests prRight = prRightsAndInterestsService.getByRightsId(trialReq.getTenantId(), rightsId);
            String merchantId = prRight.getMerchantId();
            if (!StringUtils.isBlank(merchantId)){
                if (StringUtils.isBlank(trialReq.getMerchantId())){
                    continue;
                }else {
                    if (!merchantId.contains(trialReq.getMerchantId())){
                        continue;
                    }
                }
            }
            /**
             * 过滤交易金额小于 阈值的项
             */
            BigDecimal thresholdPrice = custRightRes.getThresholdPrice();
            if(thresholdPrice == null || tranAmt.compareTo(custRightRes.getThresholdPrice()) < 0){
                continue;
            }
            String rightType = custRightRes.getRightsType();
            // 现金优惠券
            if(RightsTypeEnum.CASH_COUPON.getCode().equals(rightType)){
                BigDecimal faceValue = custRightRes.getFaceValue();
                if(faceValue == null || tranAmt.compareTo(faceValue) < 0){
                    continue;
                }
                if(trialAmount.compareTo(faceValue) < 0){
                    trialAmount = faceValue;
                    org.springframework.beans.BeanUtils.copyProperties(custRightRes,result);
                }
            }
            // 折扣券
            if(RightsTypeEnum.DISCOUNT_COUPON.getCode().equals(rightType)){
                BigDecimal discountValue = custRightRes.getDiscountValue();
                BigDecimal discountCeiling =  custRightRes.getDiscountsCeiling();
                if(discountValue == null || discountCeiling ==  null){
                    continue;
                }
                // 计算折扣值
                BigDecimal discountCal = tranAmt.multiply(BigDecimal.ONE.subtract(discountValue));

                String cycleUse = custRightRes.getCycleUse();
                // 非循环折扣券
                if(!CouponConstant.CYCLE_USE_Y.equals(cycleUse)){
                    if(discountCal.compareTo(discountCeiling) > 0 ){
                        discountCal = discountCeiling;
                    }
                }else {
                    // 循环折扣券
                    BigDecimal discountAmtUsed = custRightRes.getDiscountAmtUsed();
                    if(discountAmtUsed == null){
                        discountAmtUsed = BigDecimal.ZERO;
                    }
                    // 剩余可使用优惠总额
                    BigDecimal discountAmtAvailable = custRightRes.getDiscountAmtLimit().subtract(discountAmtUsed);
                    discountAmtAvailable = discountAmtAvailable.compareTo(discountCeiling) > 0 ? discountCeiling : discountAmtAvailable;
                    discountCal = discountCal.compareTo(discountAmtAvailable) > 0 ? discountAmtAvailable : discountCal;
                }

                if(discountCal.compareTo(trialAmount) > 0){
                    trialAmount = discountCal;
                    org.springframework.beans.BeanUtils.copyProperties(custRightRes,result);
                }
            }
        }
        result.setTrialAmount(trialAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        result.setTranAmt(tranAmt);
        if(LOGGER.isInfoEnabled()){
            LOGGER.info("优惠券试算响应：{}" , JSON.toJSONString(result));
        }
        return result;
    }

    /**
     * 优惠券 消费
     *  先试算验证，验证不一致提示重新试算，通过则正常消费优惠券
     *
     * @param couponChargeOffReq
     * @return
     */
    @Override
    public CouponTrialRes chargeOffCoupon(CouponChargeOffReq couponChargeOffReq) throws TxnBizException {
        if(LOGGER.isInfoEnabled()){
            LOGGER.info("优惠券核销请求：{}", JSON.toJSONString(couponChargeOffReq));
        }

        String rightsId = couponChargeOffReq.getRightsId();
        Long customerRightsKeyId = couponChargeOffReq.getCustomerRightsKeyId();
        BigDecimal trialAmount = couponChargeOffReq.getTrialAmount();

        // 请求参数校验
        if(StringUtils.isBlank(rightsId) || customerRightsKeyId == null || trialAmount == null){
            LOGGER.error("核销权益参数缺失必要字段：rightsId、customerRightsKeyId、trialAmount");
            throw new TxnBizException(TxnRespCode.COUPON_CHARGE_OFF_PARAM_ERR);
        }

        CouponTrialRes couponTrialRes = couponTrial(couponChargeOffReq);
        // 校验请求参数与试算结果的一致性
        boolean validateFlag = rightsId.equals(couponTrialRes.getRightsId())
                && customerRightsKeyId.equals(couponTrialRes.getId())
                && trialAmount.compareTo(couponTrialRes.getTrialAmount()) == 0;

        if(!validateFlag){
            LOGGER.info("校验请求参数与试算结果的不一致");
            throw new TxnBizException(TxnRespCode.COUPON_CHARGE_OFF_TRIAL_NOT_MATCH_ERR);
        }

        /**
         * 更新客户权益信息表
         */
        CmCustomerSecondLevel customer = customerService.getSecondLevelByCondition(couponChargeOffReq.getUserId(), couponChargeOffReq.getChannel(), couponChargeOffReq.getTenantId(), null);
        CmCustomerRightInfo customerRightInfo = extCmCustomerRightInfoMapper.selectByCustRightId(customerRightsKeyId, customer.getCustomerId(), couponChargeOffReq.getTenantId());

        String rightsType = customerRightInfo.getRightsType();
        String cycleUse = customerRightInfo.getCycleUse();
        // 如果为循环折扣券，特殊处理
        if(RightsTypeEnum.DISCOUNT_COUPON.getCode().equals(rightsType) && CouponConstant.CYCLE_USE_Y.equals(cycleUse)){
            BigDecimal discountAmtUsed = customerRightInfo.getDiscountAmtUsed();
            if(discountAmtUsed == null){
                discountAmtUsed = trialAmount;
            }else {
                discountAmtUsed = discountAmtUsed.add(trialAmount);
            }
            // 部分使用
            customerRightInfo.setRightsStatus(CouponConstant.RIGHTS_STATUS_USED_PARTLY);
            if(discountAmtUsed.compareTo(customerRightInfo.getDiscountAmtLimit()) >= 0){
                customerRightInfo.setRightsStatus(CouponConstant.RIGHTS_STATUS_USED);
            }
            customerRightInfo.setDiscountAmtUsed(discountAmtUsed);
        }else {
            customerRightInfo.setRightsStatus(CouponConstant.RIGHTS_STATUS_USED);
        }
        customerRightInfo.setUpdateTime(new Date());
        customerRightInfo.setUpdateBy(customer.getCustomerId());

        extCmCustomerRightInfoMapper.updateByPrimaryKeySelective(customerRightInfo);

        // 保存优惠券使用流水
        Integer saveFlag = saveCouponUseLog(customerRightInfo, couponChargeOffReq);
        if(LOGGER.isInfoEnabled()){
            LOGGER.info("保存affect rows：{}", saveFlag);
        }
        return couponTrialRes;
    }

    @Override
    public int insertBatch(List<CmCustomerRightInfo> customerRightInfoList) {
        return extCmCustomerRightInfoMapper.batchInsertSelective(customerRightInfoList);
    }

    private int saveCouponUseLog(CmCustomerRightInfo customerRightInfo, CouponChargeOffReq couponChargeOffReq) throws TxnBizException{
        TlCouponUseLog couponUseLog = new TlCouponUseLog();
        couponUseLog.setTenantId(customerRightInfo.getTenantId());
        couponUseLog.setChannel(customerRightInfo.getChannel());
        couponUseLog.setCustomerId(customerRightInfo.getCustomerId());
        couponUseLog.setSeqNo(couponChargeOffReq.getSeqNo());
        couponUseLog.setCustomerRightsKeyId(couponChargeOffReq.getCustomerRightsKeyId());
        couponUseLog.setTranAmt(couponChargeOffReq.getTranAmt());
        couponUseLog.setDeductAmt(couponChargeOffReq.getTrialAmount());
        couponUseLog.setDiscountAmtLimit(customerRightInfo.getDiscountAmtLimit());
        couponUseLog.setRightsId(customerRightInfo.getRightsId());
        couponUseLog.setRightsType(customerRightInfo.getRightsType());
        couponUseLog.setRightsName(customerRightInfo.getRightsName());
        couponUseLog.setCycleUse(customerRightInfo.getCycleUse());
        couponUseLog.setCreateBy(customerRightInfo.getCustomerId());
        couponUseLog.setCreateTime(new Date());
        couponUseLog.setUpdateTime(new Date());
        couponUseLog.setRecordVersionNumber(1L);
        try {
            couponUseLog.setId(iSegmentService.getId(CustomerConstant.TL_COUPON_USE_LOG));
        } catch (SegmentException e) {
            throw new TxnBizException(TxnRespCode.GET_SEGMENT_ID_ERROR);
        }
        return couponUseService.save(couponUseLog);
    }

    /**
     * 仅更新记录的部分字段
     * @param rightInfo
     */
    private void updateCustomerRightFields(CmCustomerRightInfo rightInfo) {
        extCmCustomerRightInfoMapper.updateRightStatus(rightInfo.getId(), rightInfo.getTenantId(), rightInfo.getCustomerId(), rightInfo.getRightsId(), rightInfo.getRightsStatus(), rightInfo.getRightsExchangeLogId());
    }

    /**
     * 关联兑换记录ID
     *
     * @param rightInfo
     * @param exchangeLogId
     */
    @Override
    public void updateRightExchangeId(CmCustomerRightInfo rightInfo, Long exchangeLogId) {
        rightInfo.setRightsExchangeLogId(exchangeLogId);
        this.updateCustomerRightFields(rightInfo);
    }

    /**
     * 兑换一个用户权益资格，并扣减库存
     *
     * @param rightInfo
     * @return
     */
    @Override
    public void updateRightToUsed(CmCustomerRightInfo rightInfo, String rightsId) {
        rightInfo.setRightsId(rightsId);
        rightInfo.setRightsStatus(CustomerConstant.RIGHTS_STATUS_1);
        this.updateCustomerRightFields(rightInfo);
    }

    /**
     * 恢复用户的权益资格
     *
     * @param rightInfo
     */
    @Override
    public void resetRightToUnused(CmCustomerRightInfo rightInfo) {
        rightInfo.setRightsId(null);
        rightInfo.setRightsExchangeLogId(null);
        rightInfo.setRightsStatus(CustomerConstant.RIGHTS_STATUS_0);
        this.updateCustomerRightFields(rightInfo);
    }

    /**
     * 根据客户ID和主键ID查询权益资格记录
     *
     * @param id
     * @param customerId
     * @param tenantId
     * @return
     */
    @Override
    public CmCustomerRightInfo findRightInfoById(Long id, String customerId, String tenantId) {
        return extCmCustomerRightInfoMapper.selectByIdAndCustomerId(id, customerId, tenantId);
    }

    /**
     * 根据权益兑换记录ID查询
     *
     * @param customerId
     * @param tenantId
     * @param exchangeLogId
     * @return
     */
    @Override
    public CmCustomerRightInfo findRightInfoByExchangeLogId(String customerId, String tenantId, Long exchangeLogId) {
        return extCmCustomerRightInfoMapper.selectByCustomerIdAndExchangeLogId(customerId, tenantId, exchangeLogId);
    }
}
